package wiiusej.apptest;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


import sun.font.CreatedFontTracker;
import wiiusej.*;
import wiiusej.apptest.activityTasks.ComClient;
import wiiusej.apptest.activityTasks.EnergyTransmisionTask;
import wiiusej.apptest.activityTasks.Spell;
import wiiusej.apptest.activityTasks.SpellGameTask;
import wiiusej.connection.ConnectionManager;

import wiiusej.wiiusejevents.GenericEvent;
import wiiusej.wiiusejevents.utils.WiimoteListener;
import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.spi.RootLogger;

public class WiimoteMain extends Thread{

	
	private static BlockingQueue<Spell> eneergyToComClient = new LinkedBlockingDeque<Spell>();
	
	private static final int NTHREADS = 200;
	
	private static final ExecutorService exec = 
		Executors.newFixedThreadPool(NTHREADS);
	
	private static HashMap<Integer, Wiimote> wiimotes;
	
	//Logger	
	private static Logger fileLogger;
	
	static private BlockingQueue<HashMap<Integer, BlockingQueue<GenericEvent>>> connectionToAPI;
	static private BlockingQueue<WiiUseApiEvent> apiToConnection;
	
	//Components
	static private WiiUseApiManager controller;
	static private ConnectionManager connectionManager;
	static private MessageDeliver messageDeliver;	
	
	public static void main(String[] args) {

		//Log configuration
		PropertyConfigurator.configure("log4j.properties");
		fileLogger = Logger.getLogger("main");
		
		//WiiUseApiManager.getInstance();
		fileLogger.debug("Creating Shared Cell");
				
		//COM queues
		initQueues();
		
		//System structure
		initComponents();		
		//initComClient();
		
	}		
		
	public void run(){
		
		while(true){
			//listen for end the application
			
		}
	}
	
	private static void initQueues(){		
		//COM queue from Connection Manager to WiiuseApiListener
		connectionToAPI = 
			new LinkedBlockingQueue<HashMap<Integer, BlockingQueue<GenericEvent>>>();		
		//COM queue from WiiuseApiListener to ConnectionManager - Inform about Disconnection Events
		apiToConnection = new LinkedBlockingDeque<WiiUseApiEvent>();
	}
	
	private static void initComponents(){
		
		//API listener
		//controller = new WiiUseApiManager(connectionToAPI, apiToConnection);
		controller = new WiiUseApiManager();
		
		//Connection Manager
		//connectionManager = new ConnectionManager(exec, controller, connectionToAPI, eneergyToComClient, apiToConnection);		
		//connectionManager.start();
				
		Runnable connection = 
			new ConnectionManager(exec, controller, connectionToAPI, eneergyToComClient, apiToConnection);
		
		exec.execute(connection);
		
		
		//Message Deliver - Postman
		//messageDeliver = new MessageDeliver(connectionToAPI, apiToConnection);
		
		Runnable postman = 
			new MessageDeliver(connectionToAPI, apiToConnection, controller);
		
		exec.execute(postman);
		
		//Runnable gameController = 
			//new SpellGameTask(realTimeToGameController, gameToEnergy, toRumbleQ, fromEnergyToGameQ, wiimote);
		
	}
	
	public boolean shutdownApp(){
		
		return false;
	}
	
	
	private static void initComClient(){
		
		Runnable clientServer = 
			new ComClient(eneergyToComClient, wiimotes);
		
		exec.execute(clientServer);
		
	}
	
	
}

	
